package com.zzyl.nursing.service.impl.member;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzyl.common.core.page.TableDataInfo;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.UserThreadLocal;
import com.zzyl.nursing.domain.Reservation;
import com.zzyl.nursing.mapper.ReservationMapper;

import com.zzyl.nursing.service.member.IMemberReservationService;

import com.zzyl.nursing.vo.member.TimeSlotCountVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

/**
 * 预约信息Service业务层处理
 * 
 * @author alexis
 * @date 2025-09-21
 */
@Service
public class MemberReservationServiceImpl extends ServiceImpl<ReservationMapper, Reservation> implements IMemberReservationService {
    @Autowired
    private ReservationMapper reservationMapper;

    /**
     * 查询预约信息
     *
     * @param id 预约信息主键
     * @return 预约信息
     */
    @Override
    public Reservation selectReservationById(Long id)
    {
        return reservationMapper.selectById(id);
    }

    /**
     * 查询预约信息列表
     *
     * @param reservation 预约信息
     * @return 预约信息
     */
    @Override
    public List<Reservation> selectReservationList(Reservation reservation)
    {
        return reservationMapper.selectReservationList(reservation);
    }
    /**
     * 分页查询预约信息
     * @param pageNum
     * @param pageSize
     * @param status
     * @return
     */
    @Override
    public TableDataInfo findByPage(int pageNum, int pageSize, Integer status) {

        Long userId = UserThreadLocal.getUserId();
        if(ObjectUtil.isEmpty(userId)){
            throw new BaseException("请先登录");
        }
        LambdaQueryWrapper<Reservation> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Reservation::getCreateBy,userId);
        lambdaQueryWrapper.eq(ObjectUtil.isNotEmpty(status),Reservation::getStatus,status);
        lambdaQueryWrapper.orderByDesc(Reservation::getCreateTime);
        Page page = new Page<>(pageNum,pageSize);
        page = page(page,lambdaQueryWrapper);

        return createTableDataInfo(page);
    }
    private TableDataInfo createTableDataInfo(Page page) {

        TableDataInfo tableDataInfo = new TableDataInfo();
        tableDataInfo.setRows(page.getRecords());
        tableDataInfo.setTotal(page.getTotal());
        tableDataInfo.setMsg("请求成功");
        tableDataInfo.setCode(200);
        return  tableDataInfo;
    }

    /**
     * 新增预约信息
     *
     * @param reservation 预约信息
     * @return 结果
     */
    @Override
    public int insertReservation(Reservation reservation)
    {
        return reservationMapper.insert(reservation);
    }

    /**
     * 修改预约信息
     *
     * @param reservation 预约信息
     * @return 结果
     */
    @Override
    public int updateReservation(Reservation reservation)
    {
        return reservationMapper.updateById(reservation);
    }

    /**
     * 批量删除预约信息
     *
     * @param ids 需要删除的预约信息主键
     * @return 结果
     */
    @Override
    public int deleteReservationByIds(Long[] ids)
    {
        return reservationMapper.deleteBatchIds(Arrays.asList(ids));
    }


    /**
     * 查询当天取消预约数量
     *
     * @param userId 用户ID
     * @return 取消预约数量
     */
    @Override
    public Integer getCancelledCountForToday(Long userId) {
        // 获取当天开始时间和结束时间
        long time = System.currentTimeMillis();
        LocalDateTime ldt = LocalDateTimeUtil.of(time);
        LocalDateTime startTime = ldt.toLocalDate().atStartOfDay();
        LocalDateTime endTime = startTime.plusDays(1);

        // 查询当天取消预约数量
        return reservationMapper.selectCancelledCount(userId, startTime, endTime);
    }

    @Override
    public List<TimeSlotCountVo> getReservationCountByTime() {
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        // 获取当天结束时间
        LocalDateTime endOfDay = now.toLocalDate().atStartOfDay().plusDays(1);

        // 查询每个时间段剩余预约次数
        return reservationMapper.selectReservationCountByTime(now, endOfDay);
    }

    /**
     * 新增预约
     * @param reservation 预约信息
     * @return 是否成功
     */
    @Override
    public boolean addReservation(Reservation reservation) {
        // 1. 检查当天取消预约次数是否超过3次
        Long userId = Long.valueOf(reservation.getCreateBy());
        if (getCancelledCountForToday(userId) >= 3) {
            return false; // 超过取消次数限制
        }

        // 2. 检查该时间段是否还有预约名额
        LocalDateTime reservationTime = reservation.getTime();
        LocalDateTime startOfDay = reservationTime.toLocalDate().atStartOfDay();
        LocalDateTime endOfDay = startOfDay.plusDays(1);
        List<TimeSlotCountVo> timeSlotCounts = reservationMapper.selectReservationCountByTime(startOfDay, endOfDay);

        // 查找指定时间的剩余次数
        boolean hasSlot = false;
        for (TimeSlotCountVo timeSlotCount : timeSlotCounts) {
            if (timeSlotCount.getTime().equals(reservationTime) && timeSlotCount.getCount() > 0) {
                hasSlot = true;
                break;
            }
        }

        // 如果没有找到该时间段或剩余次数为0，则检查是否为新时间段（默认6次）
        if (!hasSlot) {
            // 检查该时间段总的预约数量是否已达到6次
            int reservedCount = reservationMapper.selectReservationCountByTimeSlot(reservationTime);
            if (reservedCount >= 6) {
                return false; // 该时间段已约满
            }
        }

        // 3. 设置默认状态为待报道(0)
        reservation.setStatus(0);

        // 4. 保存预约信息
        return reservationMapper.insert(reservation) > 0;
    }
    @Override
    public boolean cancelReservation(Long id, Long userId) {
        // 查询预约信息
        Reservation reservation = reservationMapper.selectReservationById(id);
        if (reservation == null) {
            throw new RuntimeException("预约信息不存在");
        }

        // 判断预约状态是否可以取消
        if (reservation.getStatus() != null && reservation.getStatus() == 2) {
            throw new RuntimeException("该预约已取消");
        }
        // 更新预约状态为取消2
        reservation.setStatus(2);
        reservation.setUpdateTime(DateTime.now());
        reservation.setUpdateBy(String.valueOf(userId));

        // 更新数据库
        return reservationMapper.updateReservation(reservation) > 0;
    }

    @Override
    public void updateReservationStatus() {
        // 1. 查询状态=0的以及预约时间小于等于当前时间的预约，全部更新为1
        LambdaQueryWrapper<Reservation> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(Reservation::getStatus, 0);
        queryWrapper.le(Reservation::getTime, LocalDateTime.now());

        List<Reservation> reservationList = list(queryWrapper);
        if (CollectionUtils.isEmpty(reservationList)) {
            return;
        }

        // 3. 更新状态值为3
        reservationList.forEach(reservation -> {
            reservation.setStatus(3);
        });

        // 2. 批量更新
        updateBatchById(reservationList);
    }


}